package com.crowd.controller;

import com.crowd.api.MysqlRemoteService;
import com.crowd.api.RedisRemoteService;
import com.crowd.config.ShortMessageProperties;
import com.crowd.constant.CrowdConstant;
import com.crowd.po.MemberPO;
import com.crowd.util.CrowdUtil;
import com.crowd.util.ResultEntity;
import com.crowd.vo.MemberVO;
import org.assertj.core.util.Objects;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.concurrent.TimeUnit;

/**
 * @author Stone
 * @date 2020/6/28 23:38
 */
@Controller
public class MemberController {

    @Autowired
    private ShortMessageProperties shortMessageProperties;
    @Autowired
    private RedisRemoteService redisRemoteService;
    @Autowired
    private MysqlRemoteService mysqlRemoteService;

    /**
     * @Author:Stone
       * @Param phoneNum:
       * @return: com.crowd.util.ResultEntity<java.lang.String>
     * @Date: 2020/6/29 15:49
     * @Description: 发送短信功能，先发短信，成功后存入redis
    */
    @RequestMapping("auth/member/send/short/message.json")
    @ResponseBody
    public ResultEntity<String> sendMessage(@RequestParam("phoneNum") String phoneNum){
        // 1.发送验证码
        ResultEntity<String> sendResultEntity =  CrowdUtil.sendCodeByShortMessage(shortMessageProperties.getHost(),
                                            shortMessageProperties.getPath(),
                                            shortMessageProperties.getMethod(),
                                            shortMessageProperties.getAppCode(),
                                            phoneNum,
                                            shortMessageProperties.getSign(),
                                            shortMessageProperties.getSkin());
        // 2.如果发送成功，则存入redis，并且设置超时时间
        if(ResultEntity.SUCCESS.equals(sendResultEntity.getResult())){
            String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
            String code = sendResultEntity.getData();
            ResultEntity<String> redisResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 15, TimeUnit.MINUTES);
            if(ResultEntity.SUCCESS.equals(redisResultEntity.getResult())){
                return ResultEntity.successWithoutData();
            }else{
                return redisResultEntity;
            }
        }else {
            return sendResultEntity;
        }

    }

    /**
     * @Author:Stone
       * @Param memberVO:
     * @Param model:
       * @return: java.lang.String
     * @Date: 2020/6/30 22:32
     * @Description: 注册服务
    */
    @RequestMapping("/auth/do/member/register")
    public String registry(MemberVO memberVO, Model model){
        // 1.获取用户手机号
        String phoneNum = memberVO.getPhoneNum();
        // 2.拼Redis中储存验证码的key
        String key = CrowdConstant.REDIS_CODE_PREFIX+phoneNum;
        // 3.从Redis读取key中的value
        try {
            ResultEntity<String> redisStringValueByKeyRemote = redisRemoteService.getRedisStringValueByKeyRemote(key);
            // 4.检查查询操作是否有效
            String result = redisStringValueByKeyRemote.getResult();
            if(ResultEntity.SUCCESS.equals(result)){
                // 5.比较存在redis里面的验证码和表单提交的验证码
                String redisCode = redisStringValueByKeyRemote.getData();
                String formCode = memberVO.getCode();
                if(redisCode!=null && formCode!=null){
                    // 6.如果两者相等，把用户存入数据库，并且把redis里面的验证码移除
                    if(Objects.areEqual(redisCode, formCode)){
                        // 7.把VO对象转化为PO存储
                        MemberPO memberPO = new MemberPO();
                        BeanUtils.copyProperties(memberVO, memberPO);
                        // 8.执行加密
                        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
                        String beforeEncode = memberVO.getUserpswd();
                        String afterEncode = passwordEncoder.encode(beforeEncode);
                        memberPO.setUserpswd(afterEncode);
                        // 9.保存加密后的对象
                        ResultEntity<String> saveMember = mysqlRemoteService.saveMember(memberPO);
                        if(ResultEntity.SUCCESS.equals(saveMember.getResult())){
                            // 移除redis里面的key
                            redisRemoteService.removeRedisKeyRemote(key);
                        }
                        // 保存失败，有可能是账号已经存在
                        if (ResultEntity.FAILED.equals(saveMember.getResult())){
                            model.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveMember.getMessage());
                        }
                    }else {
                        // 比对不成功,输入了错误的验证码
                        model.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);
                        return "member-login";
                    }
                }
                // 如果redis里面没有这个验证码
                if(redisCode==null || redisCode.equals("")){
                    model.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_NOT_EXISTS);
                    return "member-login";
                }
                // 如果是在redis服务里面取值失败
                if(ResultEntity.FAILED.equals(result)){
                    model.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,redisStringValueByKeyRemote.getMessage() );
                    return "member-login";
                }
            }
        }
        // 当连接不上redis
        catch (Exception e){
           model.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, e.getMessage());
        }

        return "member-login";
    }
}
